第一個版本的番茄鐘叫 pomodoro-extension,一個 commit,訊息只有 init。
之後再也沒有 commit。
那時我還不熟悉 cowork 的工作流程,所以開發流程很原始:
打開 Gemini 網頁版,跟它把需求討論清楚,請它把程式碼寫出來,然後我複製貼上到編輯器裡。
現在回頭看那個 commit,技術選型使用的是 React 19 + TypeScript + Tailwind 4 + Vite,React 並不算是我最熟悉的開發語言,選擇使用 React 是與 AI 討論的過程中,AI 提供的建議而我同意的結果。
當時查到的說法是因為 AI 會選擇比較多資料的語言處理,所以在沒有指定語言的條件下,它更傾向使用 React 作為開發,但現在我知道在技術選型時,應該要多討論需求,請 AI 分析優劣最後才能選出最適合當下的開發語言
而 commit 中,核心程式只有 src/App.tsx 一個檔案,87 行。整個計時器的邏輯就這麼多:
const MODES = {
focus: 25 * 60,
short: 5 * 60,
long: 15 * 60,
};

它所包含的功能有:
bell-notification-337658.mp3
以「把想法變成能跑的東西」來看,這次體驗很好。一個晚上就有成品,沒有卡在任何技術問題上。
訊號 1:名字叫 extension,卻停在網頁
專案名稱是 pomodoro-extension,但打開資料夾會發現,可以發現還沒有瀏覽器擴充功能該有的 manifest.json。
原因很簡單:我一開始想做的是瀏覽器擴充功能。當時我工作時就會搭配著 pomofocus.io 的番茄倒數計時使用,雖然已經很不錯了,但因為覺得少了幾個我想要的東西,所以才起心動念做一個更貼近自己習慣的版本。和 AI 討論到最後,它先產出一個網頁給我。
我沒有反對,因為我想說等功能確定後,再來新增瀏覽器擴充功能該有的設定就好。
這是第一個警訊,只是我當時沒看懂:我對於為什麼要這麼做的原因不明確,鬆到 AI 可以自由發揮。
訊號 2:它只是一個番茄鐘。
這一版我沒有實際用過。不是沒開起來,而是開起來後發現它解決不了我的問題。
時間到了,網頁分頁裡響一聲。但我工作的時候不會盯著那個分頁,我在看 IDE、看文件、看設計稿。那一聲響過去就過去了,我照樣繼續做。更慘的是休息結束之後——我根本忘記要回去按「開始」,於是就這樣一路坐下去。
它只是一個番茄鐘。而我真正的問題是眼睛乾、久坐,番茄鐘只是我以為的解法。
最後我回去用 pomofocus.io,因為那樣還比較快。
我當時給 AI 的需求,大意是「做一個番茄鐘,25 分鐘專注、5 分鐘休息,時間到要提醒」。
這句話有一個關鍵的地方:它描述的是產品,不是我想改變的行為。
而 AI 只能照著我給的名詞做,但它不會主動問我「為什麼需要番茄鐘」,更不會問「時間到了以後,要怎麼保證自己會站起來」。
那個問題只有我會問,而我沒問。
這是我做完四個版本之後,我會再和 AI 協作時做的一件事。
把需求從「我要做什麼」改寫成「做完之後,我想達到什麼效果」。
格式:
做完之後,我會 ______(可觀察的行為)。
拿第一版來對照:
| 句子 | |
|---|---|
| 我當時的需求 | 做一個番茄鐘,25/5/15,時間到要提醒 |
| 應該要寫的驗收句 | 做完之後,我倒數時間停止,我會中斷目前動作離開螢幕去休息 |
如果我當初寫的是下面那句,我在做之前就會發現一件事:**一個在背景分頁響一聲的網頁,不可能讓我離開螢幕。**這個結論不需要寫完程式才知道,讀一遍就知道了。
這句話還有一個附帶好處:它會逼出真正該做的功能。「我會離開螢幕」往前推一步就是「它必須擋住我的畫面」「它必須告訴我起來要做什麼」——這正是第四版才做到、也是它成功的原因。
這個版本的價值不在程式碼,而是暴露了一件事:我把「做一個番茄鐘」當成需求本身,但那其實只是手段。真正的需求是「明顯的提示我,並且在我沒有動作的時候不會消失」,而一個在背景分頁裡響一聲的網頁,完全做不到這件事。
大概七個月後我才開始第二個版本。因為聽到朋友說了一句話:「可以做點東西放到 Steam 上銷售。」
明天講那三天之內,我的需求怎麼從「自己用」歪成「上架賣錢」,又怎麼歪回來。